import { measurementAction } from "../enum/measurement.enum"
import measuringPhaseEnum from "../enum/measuringPhase.enum"
import { DragEndEvent } from "../event/DragEvent"
import { PointerButtonEvent } from "../event/PointerEvent"
import MeasurementInput from "../mesh/MeasurementInput"
import InputIniModule, { InputSubscription } from "../module/InputIniModule"
import { LineMaterial } from "../module/LinesModule"
import MeasurementModeModule from "../module/MeasurementModeModule"
import MeasurementLineRenderer from "../renderer/MeasurementLineRenderer"
import Comparator from "../utils/Comparator"
import { Subscription } from "../utils/Subscription"

export default class MeasurementLineStyler {
  lines: any[]
  getLinesForPoint: MeasurementLineRenderer["getLinesForPoint"]
  editingMaterial: LineMaterial
  createPointSubscription: (...e) => Subscription
  getPhase: MeasurementModeModule["getPhase"]
  getSelected: MeasurementModeModule["getSelected"]
  bindings: (InputSubscription | Subscription)[]
  onDragEnd: () => void
  onClick: (e: any, _t: any, i: any) => boolean
  constructor(e, t, i, s, n: InputIniModule, r, o) {
    this.lines = e
    this.getLinesForPoint = t
    this.editingMaterial = i
    this.createPointSubscription = s
    this.getPhase = r
    this.getSelected = o
    this.bindings = []
    this.onDragEnd = () => {
      for (const e of this.lines) e.restoreLineMaterial()
    }
    this.onClick = (e, _t, i) => {
      if (this.getPhase() !== measuringPhaseEnum.IDLE) return !1
      for (const e of this.lines) e.restoreLineMaterial()
      if (!i || void 0 === i.index) return !1
      if (e.down) {
        const e = i.index
        void 0 !== e && this.styleLines(e)
      }
      return !1
    }
    this.styleLines = e => {
      const t = this.getLinesForPoint(e)
      for (const e of t) e.group === this.getSelected() && e.line.overrideLineMaterial(this.editingMaterial)
    }
    this.bindings.push(
      n.registerMeshHandler(PointerButtonEvent, Comparator.isType(MeasurementInput), this.onClick),
      n.registerUnfilteredHandler(DragEndEvent, this.onDragEnd),
      ...this.setupLineStyler(this.createPointSubscription)
    )
    this.deactivate()
  }
  styleLines: (e: number) => void
  activate() {
    for (const e of this.bindings) e.renew()
  }
  deactivate() {
    for (const e of this.bindings) e.cancel()
  }
  setupLineStyler(e: MeasurementLineStyler["createPointSubscription"]) {
    return [
      e(
        measurementAction.ADDED,
        () => {
          const e = this.lines[this.lines.length - 1]
          e && e.restoreLineMaterial()
        },
        !0
      ),
      e(
        measurementAction.UPDATED,
        (_e, t) => {
          this.styleLines(t)
        },
        !0
      )
    ]
  }
}
